home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / souper15.zip / POP3.C < prev    next >
C/C++ Source or Header  |  1996-05-18  |  12KB  |  426 lines

  1. /* $Id: pop3.c 1.5 1996/05/18 21:06:26 cthuang Exp $
  2.  *
  3.  * This module has been modified for souper.
  4.  */
  5.  
  6. /* Copyright 1993,1994 by Carl Harris, Jr.
  7.  * All rights reserved
  8.  *
  9.  * Distribute freely, except: don't remove my name from the source or
  10.  * documentation (don't take credit for my work), mark your changes (don't
  11.  * get me blamed for your possible bugs), don't alter or remove this
  12.  * notice.  May be sold if buildable source is provided to buyer.  No
  13.  * warrantee of any kind, express or implied, is included with this
  14.  * software; use at your own risk, responsibility for damages (if any) to
  15.  * anyone resulting from the use of this software rests entirely with the
  16.  * user.
  17.  *
  18.  * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
  19.  * I'll try to keep a version up to date.  I can be reached as follows:
  20.  * Carl Harris <ceharris@vt.edu>
  21.  */
  22.  
  23.  
  24. /***********************************************************************
  25.   module:       pop3.c
  26.   program:      popclient
  27.   SCCS ID:      @(#)pop3.c      2.4  3/31/94
  28.   programmer:   Carl Harris, ceharris@vt.edu
  29.   date:         29 December 1993
  30.   compiler:     DEC RISC C compiler (Ultrix 4.1)
  31.   environment:  DEC Ultrix 4.3 
  32.   description:  POP2 client code.
  33.  ***********************************************************************/
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <time.h>
  38. #include <errno.h>
  39. #include <sys/types.h>
  40. #include <sys/socket.h>
  41. #include <netinet/in.h>
  42. #include <netdb.h>
  43.  
  44. #include "socket.h"
  45. #include "souper.h"
  46.  
  47. /* requisite, venerable SCCS ID string */
  48. static char sccs_id [] = "@(#)pop3.c    2.4\t3/31/94";
  49.  
  50. /* TCP port number for POP2 as defined by RFC 937 */
  51. #define   POP3_PORT     110
  52.  
  53. /* exit code values */
  54. #define PS_SUCCESS      0       /* successful receipt of messages */
  55. #define PS_NOMAIL       1       /* no mail available */
  56. #define PS_SOCKET       2       /* socket I/O woes */
  57. #define PS_AUTHFAIL     3       /* user authorization failed */
  58. #define PS_PROTOCOL     4       /* protocol violation */
  59. #define PS_SYNTAX       5       /* command-line syntax error */
  60. #define PS_FOLDER       6       /* local folder I/O woes */
  61. #define PS_ERROR        7       /* some kind of POP3 error condition */
  62. #define PS_UNDEFINED    9       /* something I hadn't thought of */
  63.  
  64. /*********************************************************************
  65.   function:      POP3_OK
  66.   description:   get the server's response to a command, and return
  67.                  the extra arguments sent with the response.
  68.   arguments:     
  69.     argbuf       buffer to receive the argument string.
  70.     socket       socket to which the server is connected.
  71.  
  72.   return value:  zero if okay, else return code.
  73.   calls:         SockGets
  74.  *********************************************************************/
  75.  
  76. static int
  77. POP3_OK (char *argbuf, int socket)
  78. {
  79.   int ok;
  80.   char buf[BUFSIZ];
  81.   char *bufp;
  82.  
  83.   if (SockGets(socket, buf, sizeof(buf)) == 0) {
  84.     bufp = buf;
  85.     if (*bufp == '+' || *bufp == '-')
  86.       bufp++;
  87.     else
  88.       return(PS_PROTOCOL);
  89.  
  90.     while (isalpha(*bufp))
  91.       bufp++;
  92.     *(bufp++) = '\0';
  93.  
  94.     if (strcmp(buf,"+OK") == 0)
  95.       ok = 0;
  96.     else if (strcmp(buf,"-ERR") == 0)
  97.       ok = PS_ERROR;
  98.     else
  99.       ok = PS_PROTOCOL;
  100.  
  101.     if (argbuf != NULL)
  102.       strcpy(argbuf,bufp);
  103.   }
  104.   else 
  105.     ok = PS_SOCKET;
  106.  
  107.   return(ok);
  108. }
  109.  
  110.  
  111.  
  112. /*********************************************************************
  113.   function:      POP3_auth
  114.   description:   send the USER and PASS commands to the server, and
  115.                  get the server's response.
  116.   arguments:     
  117.     userid       user's mailserver id.
  118.     password     user's mailserver password.
  119.     socket       socket to which the server is connected.
  120.  
  121.   return value:  non-zero if success, else zero.
  122.   calls:         SockPrintf, POP3_OK.
  123.  *********************************************************************/
  124.  
  125. static int
  126. POP3_auth (const char *userid, const char *password, int socket) 
  127. {
  128.   int ok;
  129.   char buf[BUFSIZ];
  130.  
  131.   SockPrintf(socket,"USER %s\r\n",userid);
  132.   if ((ok = POP3_OK(buf,socket)) == 0) {
  133.     SockPrintf(socket,"PASS %s\r\n",password);
  134.     if ((ok = POP3_OK(buf,socket)) == 0) 
  135.       ;  /* okay, we're approved.. */
  136.     else
  137.       fprintf(stderr,"%s\n",buf);
  138.   }
  139.   else
  140.     fprintf(stderr,"%s\n",buf);
  141.   
  142.   return(ok);
  143. }
  144.  
  145.  
  146.  
  147.  
  148. /*********************************************************************
  149.   function:      POP3_sendQUIT
  150.   description:   send the QUIT command to the server and close 
  151.                  the socket.
  152.  
  153.   arguments:     
  154.     socket       socket to which the server is connected.
  155.  
  156.   return value:  none.
  157.   calls:         SockPuts, POP3_OK.
  158.  *********************************************************************/
  159.  
  160. static int
  161. POP3_sendQUIT (int socket)
  162. {
  163.   int ok;
  164.   char buf[BUFSIZ];
  165.  
  166.   SockPuts(socket,"QUIT");
  167.   ok = POP3_OK(buf,socket);
  168.   if (ok != 0)
  169.     fprintf(stderr,"%s\n",buf);
  170.  
  171.   return(ok);
  172. }
  173.  
  174.  
  175.  
  176. /*********************************************************************
  177.   function:      POP3_sendSTAT
  178.   description:   send the STAT command to the POP3 server to find
  179.                  out how many messages are waiting.
  180.   arguments:     
  181.     count        pointer to an integer to receive the message count.
  182.     socket       socket to which the POP3 server is connected.
  183.  
  184.   return value:  return code from POP3_OK.
  185.   calls:         POP3_OK, SockPrintf
  186.  *********************************************************************/
  187.  
  188. static int
  189. POP3_sendSTAT (int *msgcount, int socket)
  190. {
  191.   int ok;
  192.   char buf[BUFSIZ];
  193.   int totalsize;
  194.  
  195.   SockPrintf(socket,"STAT\r\n");
  196.   ok = POP3_OK(buf,socket);
  197.   if (ok == 0)
  198.     sscanf(buf,"%d %d",msgcount,&totalsize);
  199.   else
  200.     fprintf(stderr,"%s\n",buf);
  201.  
  202.   return(ok);
  203. }
  204.  
  205.  
  206.  
  207.  
  208. /*********************************************************************
  209.   function:      POP3_sendRETR
  210.   description:   send the RETR command to the POP3 server.
  211.   arguments:     
  212.     msgnum       message ID number
  213.     socket       socket to which the POP3 server is connected.
  214.  
  215.   return value:  return code from POP3_OK.
  216.   calls:         POP3_OK, SockPrintf
  217.  *********************************************************************/
  218.  
  219. static int
  220. POP3_sendRETR (int msgnum, int socket)
  221. {
  222.   int ok;
  223.   char buf[BUFSIZ];
  224.  
  225.   SockPrintf(socket,"RETR %d\r\n",msgnum);
  226.   ok = POP3_OK(buf,socket);
  227.   if (ok != 0)
  228.     fprintf(stderr,"%s\n",buf);
  229.  
  230.   return(ok);
  231. }
  232.  
  233.  
  234.  
  235. /*********************************************************************
  236.   function:      POP3_sendDELE
  237.   description:   send the DELE command to the POP3 server.
  238.   arguments:     
  239.     msgnum       message ID number
  240.     socket       socket to which the POP3 server is connected.
  241.  
  242.   return value:  return code from POP3_OK.
  243.   calls:         POP3_OK, SockPrintF.
  244.  *********************************************************************/
  245.  
  246. static int
  247. POP3_sendDELE (int msgnum, int socket)
  248. {
  249.   int ok;
  250.   char buf[BUFSIZ];
  251.  
  252.   SockPrintf(socket,"DELE %d\r\n",msgnum);
  253.   ok = POP3_OK(buf,socket);
  254.   if (ok != 0)
  255.     fprintf(stderr,"%s\n",buf);
  256.  
  257.   return(ok);
  258. }
  259.  
  260.  
  261.  
  262. /*********************************************************************
  263.   function:      POP3_readmsg
  264.   description:   Read the message content as described in RFC 1225.
  265.   arguments:     
  266.     socket       ... to which the server is connected.
  267.     mboxfd       open file descriptor to which the retrieved message will
  268.                  be written.  
  269.     topipe       true if we're writing to the system mailbox pipe.
  270.  
  271.   return value:  zero if success else PS_* return code.
  272.   calls:         SockGets.
  273.  *********************************************************************/
  274.  
  275. static int
  276. POP3_readmsg (int socket, FILE *outf)
  277. {
  278.   char buf[BUFSIZ];
  279.   char *bufp;
  280.   time_t now;
  281.   /* This keeps the retrieved message count for display purposes */
  282.   static int msgnum = 0;  
  283.  
  284.   /* Unix mail folder format requires the Unix-syntax 'From' header.
  285.      POP3 doesn't send it, so we fake it here. */
  286.   now =